package com.opcode.costa.ui.dashboard;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.graphics.Color;
import android.graphics.Paint.Align;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;

import com.opcode.costa.R;
import com.opcode.nebulamobil.base.activities.FragmentActivityBase;
import com.opcode.nebulamobil.base.fragments.FragmentBase;
import com.opcode.nebulamobil.base.fragments.dialogfragments.RoundedProgressDialogBase;
import com.opcode.nebulamobil.base.interfaces.ResponseListener;
import com.opcode.nebulamobil.information.ApplicationInfo;
import com.opcode.nebulamobil.information.dataforms.costadataforms.PersonalDataForm;
import com.opcode.nebulamobil.information.requests.costarequests.DashboardGraphicReq;
import com.opcode.nebulamobil.information.responses.JSONResponse;
import com.opcode.nebulamobil.information.responses.costaresponses.DashboardGraphicResp;
import com.opcode.nebulamobil.utility.JsonConverter;
import com.opcode.nebulamobil.utility.UniqueIdCreator;


/**
 * Bu fragment, X-Y koordinatları arasında çizgi grafiği çiizmek için
 * kullanılmaktadır.
 * 
 * @author Okan ERDOĞAN
 * 
 * 12 Eyl 2014
 */
public class ChartFragment extends FragmentBase implements ResponseListener {

	/*
	 * Grafikte gösterilecek dataları tutan nesneye ait referanstır. Bu
	 * referansın nesnesi içerisine parametre olarak veri serisi alır. Almış
	 * olduğu bu verilerle beraber graphView'u oluşturmak için kullanılır.
	 */
	private XYMultipleSeriesDataset mDataset;

	/*
	 * Grafikte gösterilecek veriler bu referansın nesnesine kayıt edilir.
	 */
	private TimeSeries mCurrentSeries;

	/*
	 * Grafiği render etmek için kullanılacak nesnedir. Render ne mi demek.
	 * Çizmek gibi bişey işte :)
	 */
	private XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();

	/*
	 * Verilerin hazır olup grafik çizmeye başlanılmasını sağlayan bool
	 * tipindeki değişkendir.
	 */
	private boolean dataReady = false;

	/*
	 * Kullanıcıya çizilen grafiği gösteren view nesnesidir.
	 */
	private GraphicalView mChartView;

	/*
	 * Fragment nesnesinin view'unu tutan değişkendir.
	 */
	private View vi;

	private Handler myHandler = null;
	private Runnable myRunnable = null;

	private DashboardGraphicResp dashboardGraphicResp;
	
	private RoundedProgressDialogBase roundedProgressDialogBase;

	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
		vi = inflater.inflate(R.layout.chart_fragment_layout, container, false);

		this.myHandler = new Handler();

		myRunnable = new Runnable() {
			public void run() {
				redraw();
			}
		};
		return vi;
	}

	/**
	 * Bu metod grafik çizimini sağlamak amacıyla çağrılıyor.
	 */
	private void createChartData(DashboardGraphicResp dashboardGraphicResp) {
		// Burada grafik çizimi için ihtiyaç duyulacak olan nesneler üretiliyor.
		// Üretilen bu nesneler daha sonra GraphView sınıfına ait nesneye
		// verilecek ve bu nesne fragment'in içine eklenecektir.
		// Böylece grafik çizim işlemimiz tamamlanmış olacaktır.
		try {
			mDataset = new XYMultipleSeriesDataset();
			mCurrentSeries = new TimeSeries(dashboardGraphicResp.getPersonalName());

			// Burada zaman dilimleri ayarlanıyor.
			for (String key : dashboardGraphicResp.getDailyPerformTreeMap().keySet()) {
				mCurrentSeries.add(getJavaDate(key), dashboardGraphicResp.getDailyPerformTreeMap().get(key));
				System.out.println(key+ ":"+ dashboardGraphicResp.getDailyPerformTreeMap().get(key));
			}

			mDataset.addSeries(mCurrentSeries);

			XYSeriesRenderer renderer = new XYSeriesRenderer();
			mRenderer.addSeriesRenderer(renderer);

			renderer.setPointStyle(PointStyle.CIRCLE);
			renderer.setGradientEnabled(true);
			renderer.setColor(Color.argb(250, 150, 200, 150));
			renderer.setLineWidth(5);
			renderer.setFillPoints(true);
			renderer.setDisplayChartValues(true);

			renderer.setPointStrokeWidth(3);

			NumberFormat nf = NumberFormat.getInstance();
			nf.setMinimumFractionDigits(2);
			nf.setMaximumFractionDigits(2);

			renderer.setChartValuesFormat(nf);
			renderer.setChartValuesTextSize(25);
			renderer.setDisplayBoundingPoints(true);
			renderer.setChartValuesSpacing(20);

			mRenderer.setApplyBackgroundColor(true);

			mRenderer.setAxisTitleTextSize(25);
			mRenderer.setPanEnabled(true, false);
			mRenderer.setZoomEnabled(true, true);
			mRenderer.setChartTitleTextSize(15);
			mRenderer.setLabelsTextSize(20);
			mRenderer.setInScroll(true);

			mRenderer.setLegendTextSize(24);

			mRenderer.setMargins(new int[] { 60, 70, 60, 40 });
			mRenderer.setZoomButtonsVisible(false);
			mRenderer.setPointSize(4);
			mRenderer.setMarginsColor(Color.argb(0x00, 0x01, 0x01, 0x01));
			mRenderer.setAxesColor(Color.WHITE);
			mRenderer.setXLabelsAlign(Align.CENTER);
			mRenderer.setXLabelsColor(Color.WHITE);
			mRenderer.setYLabelsColor(0, Color.WHITE);

			mRenderer.setYAxisAlign(Align.LEFT, 0);

			mRenderer.setYLabelsPadding(10);

			mRenderer.setYLabelsAlign(Align.RIGHT, 0);
			mRenderer.setYTitle("Performans", 0);
			mRenderer.setXTitle("Zaman");
			mRenderer.setGridColor(Color.LTGRAY);
			mRenderer.setShowGrid(false);
			mRenderer.setFitLegend(true);

			dataReady = true;
		} catch (Exception ex) {

		}
	}

	/**
	 * Parametre olarak dd.MM.yyyy formatında tarih bilgisi alır ve bu tarih
	 * bilgisine ait Date nesnesi döndürür.
	 * 
	 * @param sdate
	 * @return
	 */
	private Date getJavaDate(String sdate) {
		try {
			Date date = new SimpleDateFormat("HH:mm", Locale.ENGLISH).parse(sdate);
			return date;
		} catch (Exception ex) {
			return new Date(396478800000L);
		}
	}

	public void onResume() {
		super.onResume();
		ApplicationInfo.setResponseListener(this);
		createGraphicReq();
	}

	public void createGraphicReq() {
		((FragmentActivityBase) getActivity()).createSharedPreferencesManager("sharedpreferences", getActivity());
		String personalDataFormAsJson = ((FragmentActivityBase) getActivity()).readFromSharedPreferences("personalDataForm", null);
		PersonalDataForm personalDataForm = (PersonalDataForm) JsonConverter.fromJsonString(personalDataFormAsJson, PersonalDataForm.class);

		this.roundedProgressDialogBase=new RoundedProgressDialogBase();
		((FragmentActivityBase) getActivity()).showGeneralDialog(this.roundedProgressDialogBase, "CHART_PROGRESS_DIALOG");
		DashboardGraphicReq dashboardGraphicReq = new DashboardGraphicReq();
		dashboardGraphicReq.setRequestId(UniqueIdCreator.createUniqueID());
		dashboardGraphicReq.setType("DashboardGraphicReq");
		dashboardGraphicReq.setPersonalID(personalDataForm.getPersonelID());
		
		if(ApplicationInfo.getRequestListener()!=null){
			ApplicationInfo.getRequestListener().jsonRequestCame(JsonConverter.toJsonString(dashboardGraphicReq));
		}
	}

	private void updateGUI() {

		myHandler.post(myRunnable);
	}

	/**
	 * Grafiği yeniden çizdirmek için kullanılan metoddur.
	 */
	private void redraw() {
		if (!dataReady)
			return;

		if (mChartView == null) {
			FrameLayout layout = (FrameLayout) vi.findViewById(R.id.chart_container);
			mChartView = ChartFactory.getTimeChartView(this.getActivity(),mDataset, mRenderer, "HH:mm");
			mRenderer.setSelectableBuffer(10);
			mRenderer.setInScroll(true);
			mChartView.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {

				}
			});

			layout.addView(mChartView, new LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
			mChartView.repaint();
		} else {
			mChartView.repaint();
		}
	}

	@Override
	public void responseCame(String response) {
		JSONResponse responseObject = (JSONResponse) JsonConverter.fromJsonString(response, JSONResponse.class);

		if (responseObject.getType().equals("DashboardGraphicResp")) {
			DashboardGraphicResp dashboardGraphicResp = (DashboardGraphicResp) JsonConverter.fromJsonString(response, DashboardGraphicResp.class);
			// Grafiği çizdirmek için çağrılan metoddur.
			// Normal kullanımda bu metoda parametre olarak bir dataform
			// verilecektir.
			// Bu dataformun içerisindeki verilere göre grafik çizilecektir.
			createChartData(dashboardGraphicResp);
			updateGUI();
			((FragmentActivityBase) getActivity()).closeGeneralDialog(roundedProgressDialogBase, "CHART_PROGRESS_DIALOG");
		}

	}
}
